package com.leyou.search.service;



import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.pojo.SpuBo;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.search.client.CategoryClient;
import com.leyou.search.client.GoodsClient;
import com.leyou.search.client.SpecClient;
import com.leyou.search.pojo.Goods;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class IndexService {
    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private CategoryClient categoryClient;

    @Autowired
    private SpecClient specClient;

    public Goods buildGoods(SpuBo spuBo){
        Goods goods = new Goods();
        BeanUtils.copyProperties(spuBo,goods);
        List<String> names = categoryClient.queryNameByIds(Arrays.asList(spuBo.getCid1(), spuBo.getCid2(), spuBo.getCid3()));
        String all = spuBo.getTitle()+ StringUtils.join(names,",")+spuBo.getBname();
        goods.setAll(all);
        List<Sku> skus = goodsClient.querySkuBySpuId(spuBo.getId());
        List<Map<String,Object>> skuMapList = new ArrayList<>();
        List<Long> prices =  new ArrayList<>();

        skus.forEach(sku -> {
            Map<String,Object> skuMap = new HashMap<>();
            prices.add(sku.getPrice());
            skuMap.put("id",sku.getId());
            skuMap.put("title",sku.getTitle());
            skuMap.put("price",sku.getPrice());
            skuMap.put("image",StringUtils.isEmpty(sku.getImages())?"":sku.getImages().split(",")[0]);
            skuMapList.add(skuMap);
        });

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            goods.setSkus(objectMapper.writeValueAsString(skuMapList));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        goods.setPrice(prices);

        //获取specs可搜索的规格参数
        List<SpecParam> searchParams = this.specClient.querySpecParam(null, spuBo.getCid3(), true);

        //通用从通用规格中查询,特有从特有规格中查询
        SpuDetail spuDetail = this.goodsClient.querySpuDetailById(spuBo.getId());
        //把所有的规格参数转换成map
        Map<Long,Object> genericMap = JsonUtils.nativeRead(spuDetail.getGenericSpec(), new TypeReference<Map<Long, Object>>() {
        });
        //特殊规格
        Map<Long,List<String>> specMap = JsonUtils.nativeRead(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {
        });

        Map<String, Object> specs = new HashMap<>();//map中key 为specparam中的规格参数,value为specdetail中的对应的值

        searchParams.forEach(specParam -> {
            Long id = specParam.getId();
            String name = specParam.getName();

            Object value =null;
            if (specParam.getGeneric()) {
                value = genericMap.get(id);

                if (value != null && specParam.getNumeric()) {
                    value = this.chooseSegment(value.toString(), specParam);
                }
            }else {
                value = specMap.get(id);
            }
            if (value == null){
                value = "其他";
            }
            specs.put(name,value);
        });
        goods.setSpecs(specs);

        return goods;
    }

    private String chooseSegment(String value, SpecParam p) {
        double val = NumberUtils.toDouble(value);
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = NumberUtils.toDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if(segs.length == 2){
                end = NumberUtils.toDouble(segs[1]);
            }
            // 判断是否在范围内
            if(val >= begin && val < end){
                if(segs.length == 1){
                    result = segs[0] + p.getUnit() + "以上";
                }else if(begin == 0){
                    result = segs[1] + p.getUnit() + "以下";
                }else{
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }
}
